/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.coupon.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.codingapi.tx.annotation.TxTransaction;
import com.ykht.proj.activity.api.feign.RemoteEntService;
import com.ykht.proj.activity.entity.VEnt;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.common.core.constant.CacheConstants;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.constant.SecurityConstants;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.service.ProjUser;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.dto.UserExtDto;
import com.ykht.proj.coupon.entity.*;
import com.ykht.proj.coupon.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CnUserExtServiceImpl implements CnUserExtService {


	@Resource
	private RemoteUserService remoteUserService;

	@Resource
	private RemoteEntService remoteEntService;

/*
	@Override
	public R getUserExt(Integer userType, Long loginId) {
		try {
			switch (UserTypeEnum.getThisByVal(userType)) {
				case company:
					CnCompany company = new CnCompany().selectOne(Wrappers.lambdaQuery(CnCompany.class).eq(CnCompany::getLoginId, loginId));
					return R.ok(company);
				case brand:
					CnBrand brand = new CnBrand().selectOne(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getLoginId, loginId));
					return R.ok(brand);
				case shop:
					CnShop shop = new CnShop().selectOne(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getLoginId, loginId));
					return R.ok(shop);
				case WAITER:
					FxWaiterExt waiterExt = new FxWaiterExt().selectOne(Wrappers.lambdaQuery(FxWaiterExt.class).eq(FxWaiterExt::getLoginId, loginId).eq(FxWaiterExt::getWorkState, 1));
					return R.ok(waiterExt);
				default:
					return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed();
		}
	}*/

	/**
	 * 获取多用户 的绑定数据
	 *
	 * @param userReqList
	 * @return
	 */
//	@Override
	public R<HashMap<Integer, List>> getUserExtDtoMap(List<UserExtDto> userReqList) {
		if (userReqList == null || userReqList.size() == 0) {
			return R.ok();
		}
		HashMap<Integer, List> hashMap = new HashMap<>();

		// 根据用户类型分组 为 map类型 key 为用户类型 value 为List集合的用户对象
		Map<Integer, List<UserExtDto>> map = userReqList.stream().collect(Collectors.groupingBy(o -> o.getUserType()));
		// 遍历map对象  把 value 的 List集合 获取用户ID的集合
		map.forEach((key, value) -> {
			List<Integer> valueList = value.stream().map(UserExtDto::getUserId).collect(Collectors.toList());
			switch (UserTypeEnum.getThisByVal(key)) {
				case company:
					List<CnCompany> companyList = new CnCompany().selectList(Wrappers.lambdaQuery(CnCompany.class).in(CnCompany::getLoginId, valueList));
					Map<Integer, List<CnCompany>> companyMap = companyList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap);
					break;
				case brand:
					List<CnBrand> brandList = new CnBrand().selectList(Wrappers.lambdaQuery(CnBrand.class).in(CnBrand::getLoginId, valueList));
					Map<Integer, List<CnBrand>> companyMap1 = brandList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap1);
					break;
				case shop:
					List<CnShop> shopList = new CnShop().selectList(Wrappers.lambdaQuery(CnShop.class).in(CnShop::getLoginId, valueList));
					Map<Integer, List<CnShop>> companyMap2 = shopList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap2);
					break;
				case customer_company:

					break;
			}
		});
		return R.ok(hashMap);
	}

	/**
	 * 获取多用户 的绑定数据（根据登录人角色）
	 *
	 * @param userReqList
	 * @return
	 */
	@Override
	public R<HashMap<Integer, List>> getUserExtDtoMapLogingTyoe(List<UserExtDto> userReqList) {
		if (userReqList == null || userReqList.size() == 0) {
			return R.ok();
		}
		HashMap<Integer, List> hashMap = new HashMap<>();
		Integer userType = SecurityUtils.getUser().getUserType();
		Long sjId = SecurityUtils.getSjId();
		// 根据用户类型分组 为 map类型 key 为用户类型 value 为List集合的用户对象
		Map<Integer, List<UserExtDto>> map = userReqList.stream().collect(Collectors.groupingBy(o -> o.getUserType()));
		// 遍历map对象  把 value 的 List集合 获取用户ID的集合
		map.forEach((key, value) -> {
			List<Integer> valueList = value.stream().map(UserExtDto::getUserId).collect(Collectors.toList());
			switch (UserTypeEnum.getThisByVal(key)) {
				case company:
					List<CnCompany> companyList = new CnCompany().selectList(Wrappers.lambdaQuery(CnCompany.class)
							.in(CnCompany::getLoginId, valueList).eq(userType == 1, CnCompany::getId, sjId));
					Map<Integer, List<CnCompany>> companyMap = companyList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap);
					break;
				case brand:
					List<CnBrand> brandList = new CnBrand().selectList(Wrappers.lambdaQuery(CnBrand.class)
							.in(CnBrand::getLoginId, valueList).eq(userType == 1, CnBrand::getCompanyId, sjId)
							.eq(userType == 2, CnBrand::getId, sjId));
					Map<Integer, List<CnBrand>> companyMap1 = brandList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap1);
					break;
				case shop:
					List<CnShop> shopList = new CnShop().selectList(Wrappers.lambdaQuery(CnShop.class)
							.in(CnShop::getLoginId, valueList).eq(userType == 1, CnShop::getCompanyId, sjId)
							.eq(userType == 2, CnShop::getBrandId, sjId)
							.eq(userType == 3, CnShop::getId, sjId));
					Map<Integer, List<CnShop>> companyMap2 = shopList.stream().collect(Collectors.groupingBy(o -> o.getLoginId().intValue()));
					hashMap.putAll(companyMap2);
					break;
				case customer_company:

					break;
			}
		});
		return R.ok(hashMap);
	}


	/**
	 * 获取用户的绑定列表
	 *
	 * @param userExt
	 * @return
	 */
	@Override
	public R<List> getUserExt(UserExtDto userExt) {
		Integer status = userExt.getStatus();
		try {
			switch (UserTypeEnum.getThisByVal(userExt.getUserType())) {
				case company:
					List<CnCompany> company = new CnCompany().selectList(Wrappers.lambdaQuery(CnCompany.class).eq(CnCompany::getLoginId, userExt.getUserId()).eq(status != null, CnCompany::getDisplay, status));
					return R.ok(company);
				case brand:
					List<CnBrand> brand = new CnBrand().selectList(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getLoginId, userExt.getUserId()).eq(status != null, CnBrand::getDisplay, status));
					return R.ok(brand);
				case shop:
					List<CnShop> shop = new CnShop().selectList(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getLoginId, userExt.getUserId()).eq(status != null, CnShop::getDisplay, status));
					return R.ok(shop);
				case customer_company:
					List<VEnt> entList = remoteEntService.getByLoginId(userExt.getUserId(), SecurityConstants.FROM_IN);
					return R.ok(entList);
				default:
					return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed();
		}
	}


	/**
	 * 切换商家验证
	 *
	 * @param userExt
	 * @return
	 */
	@Override
	public R changeSj(UserExtDto userExt) {
		Integer status = userExt.getStatus();
		Model model = null;
		switch (UserTypeEnum.getThisByVal(userExt.getUserType())) {
			case company:
				model = new CnCompany().selectOne(Wrappers.lambdaQuery(CnCompany.class).eq(CnCompany::getId, userExt.getSjId()).eq(status != null, CnCompany::getDisplay, status));
				break;
			case brand:
				model = new CnBrand().selectOne(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getId, userExt.getSjId()).eq(status != null, CnBrand::getDisplay, status));
				break;
			case shop:
				model = new CnShop().selectOne(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getId, userExt.getSjId()).eq(status != null, CnShop::getDisplay, status));
				break;
		}
		return R.ok(model);
	}

	/**
	 * 绑定商家，并更新sysuser表的默认绑定商家id
	 *
	 * @param userExt
	 * @return
	 */
	@Override
	@TxTransaction(isStart = true)
	@Transactional(rollbackFor = Exception.class)
	public R bindSj(UserExtDto userExt) {
		switch (UserTypeEnum.getThisByVal(userExt.getUserType())) {
			case company:
				new CnCompany().update(Wrappers.lambdaUpdate(CnCompany.class).eq(CnCompany::getId, userExt.getSjId()).set(CnCompany::getLoginId, userExt.getUserId()).set(CnCompany::getBindTime, LocalDateTime.now()));
				break;
			case brand:
				new CnBrand().update(Wrappers.lambdaUpdate(CnBrand.class).eq(CnBrand::getId, userExt.getSjId()).set(CnBrand::getLoginId, userExt.getUserId()).set(CnBrand::getBindTime, LocalDateTime.now()));
				break;
			case shop:
				new CnShop().update(Wrappers.lambdaUpdate(CnShop.class).eq(CnShop::getId, userExt.getSjId()).set(CnShop::getLoginId, userExt.getUserId()).set(CnShop::getBindTime, LocalDateTime.now()));
				break;
		}
		SysUser user = new SysUser();
		user.setUserId(userExt.getUserId());
		user.setSjIdDefLogin(userExt.getSjId());
		return remoteUserService.bindSj(user);
	}

	@Override
	@TxTransaction(isStart = true)
	@Transactional(rollbackFor = Exception.class)
	public R unBindSj(UserExtDto userExt) {
		SysUser user = new SysUser();
		user.setUserId(userExt.getUserId());
		R<List> r = this.getUserExt(userExt);

		switch (UserTypeEnum.getThisByVal(userExt.getUserType())) {
			//根据时间排序倒序排序，获取除了当前的解绑商家id之外的第一个，
			// 第一个有值则穿个upms服务，进行绑定sjid
			//没值，upms服务则给默认登录商家id  重置为null
			case company:
				List<CnCompany> companyList = r.getData();
				Optional<CnCompany> optCompany = companyList.stream().filter(o -> o.getId() != userExt.getSjId()).sorted(Comparator.comparing(CnCompany::getCreateTime).reversed()).findFirst();
				optCompany.ifPresent(opt -> user.setSjIdDefLogin(opt.getId()));
				new CnCompany().update(Wrappers.lambdaUpdate(CnCompany.class).eq(CnCompany::getId, userExt.getSjId()).set(CnCompany::getLoginId, null).set(CnCompany::getBindTime, null));
				break;
			case brand:
				List<CnBrand> cnBrandList = r.getData();
				Optional<CnBrand> optBrand = cnBrandList.stream().filter(o -> o.getId() != userExt.getSjId()).sorted(Comparator.comparing(CnBrand::getCreateTime).reversed()).findFirst();
				optBrand.ifPresent(opt -> user.setSjIdDefLogin(opt.getId()));
				new CnBrand().update(Wrappers.lambdaUpdate(CnBrand.class).eq(CnBrand::getId, userExt.getSjId()).set(CnBrand::getLoginId, null).set(CnBrand::getBindTime, null));
				break;
			case shop:
				List<CnShop> cnShopList = r.getData();
				Optional<CnShop> optional = cnShopList.stream().filter(o -> o.getId() != userExt.getSjId()).sorted(Comparator.comparing(CnShop::getCreateTime).reversed()).findFirst();
				optional.ifPresent(opt -> user.setSjIdDefLogin(opt.getId()));
				new CnShop().update(Wrappers.lambdaUpdate(CnShop.class).eq(CnShop::getId, userExt.getSjId()).set(CnShop::getLoginId, null).set(CnShop::getBindTime, null));
				break;
		}
		return remoteUserService.unBindSj(user);
	}

	/**
	 * 下家商家
	 *
	 * @param userExt
	 * @return
	 */
	@Override
	public R offSj(UserExtDto userExt) {
		Integer status = 1;//下架
		switch (UserTypeEnum.getThisByVal(userExt.getUserType())) {
			case company:
				//下架公司
				new CnCompany().update(Wrappers.lambdaUpdate(CnCompany.class).set(CnCompany::getDisplay, status).eq(CnCompany::getId, userExt.getSjId()));
				List<CnBrand> brandList = new CnBrand().selectList(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getCompanyId, userExt.getSjId()));
				brandList.stream().forEach(o -> this.offSj(new UserExtDto(UserTypeEnum.brand.getValue(), null, o.getId(), status)));
				break;
			case brand:
				//下架品牌
				new CnBrand().update(Wrappers.lambdaUpdate(CnBrand.class).set(CnBrand::getDisplay, status).eq(CnBrand::getId, userExt.getSjId()));
				//下架品牌下所有优惠券
				new CnCoupon().update(Wrappers.lambdaUpdate(CnCoupon.class).set(CnCoupon::getStatus, status).eq(CnCoupon::getBrandId, userExt.getSjId()));
				//下架品牌分销配置
				List<CnShop> shopList = new CnShop().selectList(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getBrandId, userExt.getSjId()));
				shopList.stream().forEach(o -> this.offSj(new UserExtDto(UserTypeEnum.brand.getValue(), null, o.getId(), status)));
				break;
			case shop:
				//下架门店
				new CnShop().update(Wrappers.lambdaUpdate(CnShop.class).set(CnShop::getDisplay, status).eq(CnShop::getBrandId, userExt.getSjId()));
				new CnShop().update(Wrappers.lambdaUpdate(CnShop.class).set(CnShop::getDisplay,status).eq(CnShop::getBrandId,userExt.getSjId()));
				new CnCoupon().update(Wrappers.lambdaUpdate(CnCoupon.class).set(CnCoupon::getStatus,status).eq(CnCoupon::getBrandId,userExt.getSjId()));
				//下架分销配置
				break;
		}

		return null;
	}
//
//	public static void main(String[] args) {
//		SysUser user = new SysUser();
//		user.setUserId(1);
//		CnCompany company = null;
//		 company = new CnCompany();
//		company.setId(1l);
//
//		Optional<CnCompany> opt = Optional.ofNullable(company);
//		opt.ifPresent(u -> System.out.println("Username is: " + u.getId()));
//		opt.ifPresent(u -> {
//			user.setSjIdDefLogin(u.getId());
//		});
//		System.out.println(JSONUtil.toJsonStr(user));
//		List list = ListUtil.empty();
//		System.out.println(list.size());
//
//
//	}

}